package com.caishi.lkx.exam.api;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.caishi.lkx.common.AdminBaseApi;
import com.caishi.lkx.common.context.RequireContext;
import com.caishi.lkx.common.context.Role;
import com.caishi.lkx.common.ienum.DeviceType;
import com.caishi.lkx.common.role.Roles;
import com.caishi.lkx.exam.model.ExamModel;
import com.caishi.lkx.exam.model.IndustryModel;
import com.caishi.lkx.exam.service.IExamService;
import com.caishi.lkx.exam.service.IIndustryService;
import com.caishi.lkx.exam.service.impl.IndustryServiceImpl;
import com.caishi.lkx.user.service.IAgentUserService;
import com.caishi.lkx.user.service.IGroupService;
import com.zzw.common.entity.impl.BaseEntity;
import com.zzw.common.utils.CommonUtil;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.stream.Collectors;


@Tag(name = "行业相关")
@Slf4j
@RestController
@RequestMapping("/exam/industry")
public class IndustryApi extends AdminBaseApi<IIndustryService, IndustryModel, String> {

    @Resource
    private IIndustryService industryService;

    @Resource
    private IExamService examService;

    @Resource
    private IGroupService groupService;

    @Resource
    private IAgentUserService  agentUserService;

    @Override
    public IIndustryService loadService() {
        return industryService;
    }



    @Operation(summary = "获取行业")
    @GetMapping("/app/list")
    @Roles
    @RequireContext({Role.APP,Role.CHANNEL,com.caishi.lkx.common.context.Role.PC})
    public List<IndustryModel> list(){
        var res = loadService().selectList(new LambdaQueryWrapper<IndustryModel>());

        Long groupId = context.getGroupId();
        if(groupId != null && groupId > 0L){
            // "industryActionIds": ["caikuailei", "jiangonglei", "zhicheng"]
            List<String> haveIndRoleList =   groupService.getById(groupId).getPermissionMap().get(0).getIndustryActionIds();
            if(!haveIndRoleList.isEmpty())
                return  res.stream().filter(in->haveIndRoleList.contains(in.getId())).collect(Collectors.toList());
        }

        return res;
    }
    @Operation(summary = "代理商获取行业")
    @GetMapping("/agent/list")
    @Roles
    public List<IndustryModel> agentlist(){
        var res = loadService().selectList(new LambdaQueryWrapper<IndustryModel>());
        var userId = userContext.currentUserId();
        Long groupId = agentUserService.getById(userId).getBindGroupId();
        if(groupId != null && groupId > 0L){
            List<String> haveIndRoleList =   groupService.getById(groupId).getPermissionMap().get(0).getIndustryActionIds();
            if(!haveIndRoleList.isEmpty())
                return  res.stream().filter(in->haveIndRoleList.contains(in.getId())).collect(Collectors.toList());
        }

        return res;
    }

    @Override
    @Roles
    public List<IndustryModel> list(@RequestParam(defaultValue = "10") Integer size, @ModelAttribute IndustryModel model, @NotNull JSONObject otherParam) {
        var dt = userContext.currentTokenData().getDevice();
        var res = super.list(size, model, otherParam);
        if (dt != DeviceType.admin && userContext.loginStatus()) {
            var userIndustry = industryService.userHaveIndustry(userContext.currentLocalGroupId(), userContext.currentGroupId(), userContext.currentUserId());
            if (!userIndustry.getAll().isEmpty())
                res.sort(IndustryServiceImpl.permissionComparator(userIndustry.getAll().toArray(String[]::new)));
            var u = userIndustry.getUser().toArray(String[]::new);
            var g = userIndustry.getGroup().toArray(String[]::new);
            for (var item: res) {
                byte r = CommonUtil.binarySearch(u, item.getId()) ? (byte) 0x01 : 0x00;
                r |= CommonUtil.binarySearch(g, item.getId()) ? 0x02 : 0x00;
                item.setAuthFlag(r);
            }
        }
        return res;
    }

    @Override
    protected LambdaQueryWrapper<IndustryModel> baseWrapper(IndustryModel model, JSONObject otherParam) {
        String searchKey = otherParam.getStr("searchKey");
        var res = super.baseWrapper(model, otherParam).like(StrUtil.isNotBlank(searchKey), IndustryModel::getName, searchKey);
        var dt = userContext.currentTokenData().getDevice();
        if (dt != DeviceType.admin && !userContext.loginStatus()) {
            var permission = groupPermission();
            if (permission != null) {
                if (permission.isEmpty()) res.eq(BaseEntity::getId, "noId");
                else res.in(BaseEntity::getId, permission);
            }
        }
        return res;
    }

    @Override
    protected List<IndustryModel> listCover(List<IndustryModel> result, JSONObject otherParam) {
        boolean haveExamCount = otherParam.getBool("haveExamCount", false);
        boolean haveExamList = otherParam.getBool("haveExamList", false);
        boolean pcIndex = otherParam.getBool("pcIndex", false);
        if (haveExamCount || haveExamList || pcIndex) {
            result.parallelStream()
                    .forEach(i -> {
                        if (haveExamCount) {
                            i.setExamCount(examService.selectCount(
                                    examService.wrappers()
                                            .eq(ExamModel::getIndustryId, i.getId())
                            ).intValue());
                        }
                        if (haveExamList || pcIndex && result.indexOf(i) < 4) {
                            i.setExams(examService.industryExam(i.getId()));
                        }
                    });
        }
        return super.listCover(result, otherParam);
    }


    private List<String> groupPermission() {
        return industryService.groupPermission(userContext.currentLocalGroupId(), userContext.currentGroupId(), userContext.currentUserId());
    }

}
